package com.pbdatabase.core.indexer;

import com.pbdatabase.core.main.PropertyManager;
import org.apache.log4j.Logger;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 * Most un-optimal indexer implementation. Only to be used for prototyping
 */
public class InMemoryIndexer implements Indexer {
	private static Logger _logger = Logger.getLogger(InMemoryIndexer.class);
	private Map index = null;
	private String name = null;

	@Override
	public void addRecord(Object key, Object value) {
		_logger.debug("Adding record to index");
		if (index.containsKey(key)) {
			List<Object> indexed = (List<Object>) index.get(key);
			indexed.add(value);
			return;
		}
		List<Object> indexed = new ArrayList<Object>();
		indexed.add(value);
		index.put(key, value);
		persistIndex();
	}

	@Override
	public List<Object> getRecord(Object key) {
		_logger.debug("Trying to retrieve record");
		String messageFile = PropertyManager.getInstance().getMessageLocation();
		List<String> messageFiles = (List<String>) index.get(key);
		List<Object> messages = new ArrayList<Object>();
		for (String fileName : messageFiles) {
			File file = new File(messageFile + fileName);
			FileInputStream fin = null;
			try {
				fin = new FileInputStream(file);
				byte fileContent[] = new byte[(int)file.length()];

				fin.read(fileContent);
				messages.add(fileContent);
			}
			catch (Exception ex) {
				_logger.error("Issue with reading object", ex);
			}
			finally {
				try {
					if (fin != null) {
						fin.close();
					}
				} catch (Exception e) { }
			}
		}
		return messages;
	}

	@Override
	public void deleteRecord(Object key) {
		// Not deleting anything yet
	}

	@Override
	public void initialize(String name) {
		String indexLocation = PropertyManager.getInstance().getIndexLocation();
		ObjectInputStream ois = null;
		this.name = name;
		try {
			FileInputStream fis = new FileInputStream(indexLocation + "/" + name + "_index.ser");
			ois = new ObjectInputStream(fis);
			index = (Map) ois.readObject();
			_logger.debug("Initializing index");
		} catch (Exception ex) {
			_logger.error("Issue with getting index", ex);
			index =  new HashMap<String, List<Object>>();
		} finally {
			if (null != ois) {
				try {
					ois.close();
				} catch (Exception e) { }
			}
		}
	}

	private void persistIndex() {
		String indexLocation = PropertyManager.getInstance().getIndexLocation();
		ObjectOutputStream oos = null;
		try {
			FileOutputStream fos = new FileOutputStream(indexLocation + "/" + name + "_index.ser");
			oos = new ObjectOutputStream(fos);
			oos.writeObject(index);
			_logger.debug("Saved index");
		} catch (Exception ex) {
			_logger.error("Issue with saving index", ex);
		} finally {
			if (oos != null) {
				try {
					oos.close();
				} catch (Exception e) { }
			}
		}
	}
}
